package ar.com.utn.openqsb.main;

import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Toolkit;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

import ar.com.utn.openqsb.commons.util.LanguageUtil;
import ar.com.utn.openqsb.commons.util.Utility;

/**
 * 
 * This class represents the main window, it is the launch panel for all the
 * modules.
 * 
 * @author rvega
 * @author aprieto
 */
public class Launcher extends JFrame {

	private static final long serialVersionUID = 1L;

	/** Base file name where the configuration will be taken. */
	public static final String BASE_NAME = "ar.com.utn.openqsb.configuration.apps";

	private static final String HEADER_LOGO = "ar/com/utn/openqsb/icons/logo.jpg";

	/**
	 * Build main window.
	 */
	public Launcher() {
		super(LanguageUtil.getLocalizedMessage("main.title"));
	}

	/**
	 * Load configuration and create launcher buttons.
	 */
	public void configure() {

		// set onClose default operation.
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// clean layout manager, we will use (x,y) coordinates.
		setLayout(null);

		// set size and position of the window.
		setPreferredSize(new Dimension(800, 560));
		setResizable(false);
		setMinimumSize(new Dimension(800, 560));
		pack();
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation((d.width - getWidth()) / 2, (d.height - getHeight()) / 2);

		// add header logo
		JLabel header = new JLabel();
		header.setIcon(Utility.getIcon(HEADER_LOGO));
		Insets insets = getInsets();
		Dimension size = header.getPreferredSize();
		header.setBounds(0 + insets.left, 0 + insets.top, size.width,
				size.height);
		add(header);

		// finally, parse configuration and create launcher buttons.
		Map<String, Config> mapConfig = parseConfig();
		Iterator<Map.Entry<String, Config>> it = mapConfig.entrySet()
				.iterator();
		int initialX = 50;
		int initialY = 150;
		while (it.hasNext()) {
			Map.Entry<String, Config> e = it.next();
			Config config = e.getValue();
			JButton button = new JButton();
			button.setIcon(Utility.getIcon(config.getIcon()));
			button.setText(LanguageUtil.getLocalizedMessage(config.getLang(),
					"title"));
			button.addActionListener(new LauncherActionListener(config
					.getClazz()));
			insets = getInsets();
			size = button.getPreferredSize();
			button.setBounds(initialX + insets.left, initialY + insets.top,
					size.width, size.height);
			initialY += 70;
			add(button);
		}
	}

	/**
	 * Load app.properties into a {@link Map}.
	 * 
	 * @return a {@link Map}. The key is the module id and the value a
	 *         {@link Config} object containing all the initialization
	 *         parameters.
	 */
	private Map<String, Config> parseConfig() {
		ResourceBundle bundle = ResourceBundle.getBundle(BASE_NAME);
		Map<String, Config> mapConfig = new HashMap<String, Config>();
		Enumeration<String> en = bundle.getKeys();
		while (en.hasMoreElements()) {
			String key = en.nextElement();
			String[] splitArray = key.split("[.]");
			String app = splitArray[0];
			String property = splitArray[1];

			// already loaded information for this module ?
			if (!mapConfig.containsKey(app)) {
				mapConfig.put(app, new Config());
			}
			// set the parameters into the configuration object.
			Config config = mapConfig.get(app);
			if (property.equals("icon")) {
				config.setIcon(bundle.getString(key));
			} else if (property.equals("class")) {
				config.setClazz(bundle.getString(key));
			} else if (property.equals("lang")) {
				config.setLang(bundle.getString(key));
			} else {
				// FIXME rvega Use log4j here.
				System.err.println("Propiedad " + property + " desconocida");
			}
		}
		return mapConfig;
	}

	/**
	 * Configuration model.
	 * 
	 * @author rvega
	 * 
	 */
	class Config {

		private String icon;

		private String clazz;

		private String lang;

		/**
		 * @return the icon
		 */
		public String getIcon() {
			return icon;
		}

		/**
		 * @param icon
		 *            the icon to set
		 */
		public void setIcon(String icon) {
			this.icon = icon;
		}

		/**
		 * @return the clazz
		 */
		public String getClazz() {
			return clazz;
		}

		/**
		 * @param clazz
		 *            the clazz to set
		 */
		public void setClazz(String clazz) {
			this.clazz = clazz;
		}

		/**
		 * @return the lang
		 */
		public String getLang() {
			return lang;
		}

		/**
		 * @param lang
		 *            the lang to set
		 */
		public void setLang(String lang) {
			this.lang = lang;
		}

	}
}
